package leetcode.monotoni;

import java.util.ArrayDeque;
import java.util.Arrays;
import java.util.Deque;

/**
 * 85. 最大矩形
 * 给定一个仅包含 0 和 1 、大小为 rows x cols 的二维二进制矩阵，找出只包含 1 的最大矩形，并返回其面积。
 * <p>
 * <p>
 * <p>
 * 示例 1：
 * <p>
 * <p>
 * 输入：matrix = [["1","0","1","0","0"],["1","0","1","1","1"],["1","1","1","1","1"],["1","0","0","1","0"]]
 * 输出：6
 * 解释：最大矩形如上图所示。
 * 示例 2：
 * <p>
 * 输入：matrix = []
 * 输出：0
 * 示例 3：
 * <p>
 * 输入：matrix = [["0"]]
 * 输出：0
 * 示例 4：
 * <p>
 * 输入：matrix = [["1"]]
 * 输出：1
 * 示例 5：
 * <p>
 * 输入：matrix = [["0","0"]]
 * 输出：0
 * <p>
 * <p>
 * 提示：
 * <p>
 * rows == matrix.length
 * cols == matrix[0].length
 * 1 <= row, cols <= 200
 * matrix[i][j] 为 '0' 或 '1'
 */
public class MaximalRectangle {
    public static void main(String[] args) {


    }


    public int maximalRectangle(char[][] matrix) {
        int length = matrix.length;
        if (length == 0) {
            return 0;
        }
        int high = matrix[0].length;

        int[] heights = new int[high + 1];
        heights[high] = -1;
        int ans = 0;

        // 把前n行当做第 84 题的柱状图
        for (int row = 0; row < length; row++) {
            for (int col = 0; col < high; col++) {
                heights[col] = matrix[row][col] == '1' ? heights[col] + 1 : 0;
            }

            int[] heightsT = Arrays.copyOf(heights, high + 1);
            int rowMax = largestRectangleArea(heightsT);
            ans = Math.max(ans, rowMax);
        }
        return ans;
    }

    // 拷贝自 84 题目
    public int largestRectangleArea(int[] heights) {

        int len = heights.length;
        if (len == 0) {
            return 0;
        }
        if (len == 1) {
            return heights[0];
        }

        int ans = 0;
        int[] arr = new int[len + 2];
        // arr需要比heights大两个单位，作为首尾的边界,值都为0
        for (int i = 1; i < arr.length - 1; i++) {
            arr[i] = heights[i - 1];
        }

        Deque<Integer> stack = new ArrayDeque<>();

        // 从左往右遍历
        for (int i = 0; i < arr.length; i++) {
            // i == 0 时 arr[i] == 0,先put个0进去垫底
            // i == length-1 时 arr[length-1] == 0,肯定可以进入while处理
            while (!stack.isEmpty() && arr[i] < arr[stack.peek()]) {
                int curHigh = arr[stack.pop()];

                if (!stack.isEmpty()) {
                    int temp = curHigh * (i - stack.peek() - 1);
                    ans = Math.max(temp, ans);
                }

            }
            stack.push(i);
        }

        return ans;
    }
}
